[pull] master from DataDog:master#637
Merged
Merged
Conversation
* feat(nutanix): add collect_resource_ids_as_tags option Adds an opt-in instance option that attaches Nutanix resource extId values as tags on cluster, host, and VM infrastructure metrics, so Datadog metrics can be correlated with specific Nutanix resources. Defaults to false because the tags are high cardinality (one unique value per resource). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(nutanix): add changelog entry for #24303 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
) * Bundle per-job correlation into BatchFinished via BatchJobResult Move the job spec / workflow-run / artifact-directory correlation out of the gatherer and into the TaskTestRunner producer, shipping it as a single enriched per-job BatchJobResult on BatchFinished. - BatchJob.artifact_name(): deterministic, collision-free, sanitized artifact name derived solely from the job's frozen fields. Replaces the gatherer's delimiter-bounded token match as the way a job's artifact directory is resolved. - BatchJobResult bundles the BatchJob spec, the matched WorkflowJob (or None), and the resolved artifact path (or None). - BatchFinished now carries batch_jobs; the runner joins each job to its workflow job by name and resolves its artifact directory by artifact name, tolerating missing API matches and missing artifacts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * updates * updates * updates * updates * Address review comments: BatchJobResult.correlate factory and focused tests - Move correlation logic from TaskTestRunner._build_batch_jobs into a BatchJobResult.correlate static factory so it is testable without the processor. - _download_artifacts returns only the artifact-name -> path map; artifacts_path is taken from the runner options. - test_messages.py: explicit-args batch_job factory, drop the tautological determinism test, add direct correlate tests. - test_task_test_runner.py: drop underscore-prefixed helpers and split the monolithic happy-path test into one-concern-per-test cases via a shared helper. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add changelog entry Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Change changelog entry type to fixed Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* kafka_consumer: add Confluent Cloud Connect support Collect connector metrics and configuration events from the Confluent Cloud Connect REST API via the kafka_connect_confluent_cloud_environment_id, kafka_connect_confluent_cloud_cluster_id, and kafka_connect_confluent_cloud_url options. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * kafka_consumer: stop placeholder Confluent Cloud IDs becoming config defaults Add display_default: null to kafka_connect_confluent_cloud_environment_id and kafka_connect_confluent_cloud_cluster_id so the example IDs are not baked into defaults.py and conf.yaml.example. Also document that authentication uses kafka_connect_username/password (Confluent Cloud API key/secret). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * kafka_consumer: harden Confluent Cloud URL fallback and dedupe gating predicate Coerce an explicit-null kafka_connect_confluent_cloud_url to the default base URL to avoid AttributeError on None.rstrip(). Add a confluent_cloud_configured property on KafkaConfig and use it in both _collect_connect_status and _confluent_cloud_key so the gating rule lives in one place. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * kafka_consumer: test Confluent Cloud path emits metrics and config events Add test_confluent_cloud_emits_metrics_and_config_events asserting that with Confluent Cloud configured the run emits kafka.connector.count=2 and connector config events whose connect_url targets the Confluent Cloud endpoint. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * kafka_consumer: support Confluent Cloud Connect generically via response-driven expand fallback Remove the Confluent-Cloud-specific config options and collection code. Confluent Cloud's Connect REST API is OSS-shaped and reachable by pointing kafka_connect_url at the Cloud base path with a Cloud API key as basic auth, so it needs no special handling beyond tolerating its single-expand behavior. Make _collect_rest response-driven: it issues one combined expand=info&status request and, only when a section comes back null (as Confluent Cloud does, honoring one expand value per request), fetches the missing section and merges it. OSS workers return both sections in the combined call, so behavior and request count are unchanged for self-hosted Connect. Also tolerate explicit null info/status values when emitting metrics and config events. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Apply review fixes for Confluent Cloud Connect support - Guard None connector entries in both _emit_connector_metrics and _emit_connector_config_events so a null entry no longer crashes a URL's whole collection. - _merge_expand: only assign a section when the fallback value is not None, avoiding overwriting with an explicit None. - Supplementary expand fetches now degrade gracefully: each is wrapped in try/except that logs a warning and emits partial data instead of marking the endpoint unreachable. - Add type hints to the new _merge_expand method and _fetch closure. - Clarify the Confluent Cloud auth note in spec.yaml: API key (ID) goes in kafka_connect_username and the secret in kafka_connect_password; regenerate conf.yaml.example. - Strengthen test_single_expand_sections_merged to assert the merged info surfaces in the config event, and add an OSS single-request invariant test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * kafka_consumer: condense verbose connector comments to one line Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * kafka_consumer: retry combined expand as single value for Confluent Cloud Confluent Cloud's Connect v1 expansions endpoint ignores a combined expand list (serialized as repeated query params) and returns the unexpanded connector-name list instead, so the response fell into the pre-2.3 bail-out path before the single-expand fallback could run. Retry with one expand value before giving up. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… fails (#24263) * Don't abort kafka_consumer when one partition's high-watermark lookup fails The high-watermark offset collection issues a single batched offsets_for_times call for all topic-partitions. If any partition cannot be resolved at all (e.g. a leaderless/offline RF-0 or mid-deletion topic), librdkafka raises a KafkaException (UNKNOWN_TOPIC_OR_PART) for the entire batch call, which propagates up and aborts the whole check so no metrics are collected. Fall back to per-partition lookups when the batched call fails, skipping only the partitions that still raise, so healthy partitions are still collected and the check is not aborted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add changelog entry for PR #24263 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Fetch high-watermark offsets via AdminClient.list_offsets Replace the resilient-but-clunky offsets_for_times approach with AdminClient.list_offsets, which returns a future per partition. Errored partitions (e.g. leaderless/offline topics that raise UNKNOWN_TOPIC_OR_PART) are skipped individually, so healthy partitions are still collected without a wholesale raise or a per-partition retry loop. list_offsets is also the purpose-built API for latest/earliest offsets, unlike offsets_for_times with sentinel timestamp values. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Apply review fixes: degrade highwater offset collection gracefully Mirror cluster_metadata.fetch_earliest_offsets in get_partition_offsets: broaden the per-future handler to catch any Exception so one bad partition does not abort the loop, and wrap the outer list_offsets call so a request/broker-level failure logs a warning and returns [] instead of aborting the whole highwater collection. Strengthen unit tests: assert list_offsets is called with isolation_level=READ_UNCOMMITTED and the request timeout, cover the non-Kafka per-partition error and request-level failure paths, and add an empty-partitions test that issues no request. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * kafka_consumer: shorten get_partition_offsets docstring Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Re-raise on full-request list_offsets failures in get_partition_offsets A request-level failure was being swallowed into an empty result, so highwater offsets silently defaulted to 0 for every partition and corrupted partition.size/topic.size metrics instead of skipping them. Only individual partition lookup failures should be tolerated; a full-request failure should abort highwater collection like before. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Extend `release branch tag` with `--release`, `--ref`, `--rc N`, and `--yes` The command previously required the user to be on the release branch and only let them pick between `--rc` and `--final`. The new flags make it possible to tag a release branch from anywhere, pin or auto-suggest the RC number, and tag an arbitrary commit instead of the branch tip: - `--release/-r <X.Y[.x]>` selects the target release branch; if not on it, a worktree is created at `.worktrees/release-tag/<branch>` from `origin/<branch>` and torn down on success. - `--ref <commit>` tags the given commit (must be an ancestor of `origin/<branch>`) instead of the branch tip. - `--rc` accepts an optional value: `--rc` alone auto-suggests, `--rc N` pins. Warns when N skips ahead of the next available RC. - `--yes/-y` skips all yes/no confirms. * Add changelog entry * Apply round 1 review feedback and fix mypy lint - `GitRepository.tag()` now uses its `message` parameter instead of the tag name (pre-existing bug: `--message` was always set to `value`). - Compute `current_branch` once and thread it into `_resolve_target_branch` to avoid the duplicate `git rev-parse` subprocess call. - Move worktree setup inside the try/finally so any failure between worktree creation and teardown still triggers the inspection warning. - Narrow the OSError catch to just `git.tag` / `git.push` so other failures surface with their own attributable messages. - `_branch_exists_on_origin` no longer swallows OSError as "branch missing" — split into `_ensure_branch_on_origin` that distinguishes a real ls-remote failure from an empty result. - Confirmation prompt for `--ref` shows the resolved commit SHA, not the raw user input, so the user can verify what `rev-parse` resolved to. - Renamed `_create_or_refresh_worktree` to `_create_worktree` (it only adds) and the failure message now hints at the manual cleanup command. - Added an `exit_code` assertion to `test_no_worktree_when_already_on_target_branch`. - Input-validation helpers now raise `click.UsageError` so mypy follows the `NoReturn` semantics; updated the two affected tests to assert non-zero exit instead of exit code 1 (UsageError exits with 2). * Apply round 2 review feedback - Drop unused `app` arg from `_parse_rc_value` (it raises `click.UsageError` directly and never needed application state). - Include the underlying git error text in the `--ref` failure messages for both `rev-parse` and `merge-base --is-ancestor`. - Remove dead post-`range` guard in `_warn_on_rc_gap`. - Annotate `_check_open_prs` return as `list[PullRequest]`. - Rename changelog entry from `.added` to `.changed`: the new confirm prompt on a release branch is a behavior change for non-interactive callers that piped a single `y`. - Replace the `capture.return_value` fixture default with a side_effect callable that dispatches on the first argument, so new code paths that call `capture()` without an explicit override don't silently inherit the `ls-remote` payload. - Use a `_make_ref_dispatcher` helper in `--ref` tests so the mocked responses are keyed by subcommand instead of call order. - Extract `_worktree_subcommands(git, sub)` helper to dedupe the worktree-call assertions. * Apply round 3 review feedback - `--final` + `--rc` now raises `click.UsageError` (exit code 2) to match the other CLI-validation errors in the command. - Change the `RC_AUTO` sentinel to a private, unguessable string so `--rc auto` is no longer silently equivalent to bare `--rc`. - Merge `_resolve_tag_ref`'s two try/except blocks; the branch that picks the abort message keys off whether `commit_sha` was bound, which avoids the possibly-unbound warning some type-checkers emit. - `_warn_on_rc_gap` now uses `app.display_warning` to match the other new helpers in this PR. - Test additions: full call-shape assertions on the `worktree add` / `worktree remove` invocations, plus a new test that covers the `_create_worktree` abort path and its manual-cleanup hint. * Normalize backslashes in worktree path assertions for Windows * Extract helpers from `tag()` body to read as a recipe The command body had four logical phases interleaved with the worktree lifecycle. Each phase is now its own helper: - `_prepare_working_dir` decides between pull-in-place and worktree creation, returns `(git, working_dir, worktree_created)`. - `_warn_if_build_agent_yaml_stale` surfaces the recovery warning and returns whether the workflow dispatch is needed. - `_compute_new_tag` owns the existing-tag collection, RC resolution, and all RC validations (bounds, exists, gap, backward move). - `_confirm_and_push_tag` owns the open-PR check, the final confirm prompt, and the `git tag` / `git push` pair. The main `tag()` body shrinks from ~108 to ~35 lines and reads top-to-bottom as the steps of a tagging operation. The worktree `try/finally` stays in the main body — a future change can replace it with a context manager once worktree management is consolidated across the codebase. * Tag directly against `origin/<branch>` instead of via a worktree The previous design checked out the target branch in a worktree under `.worktrees/release-tag/<branch>/` and ran the tag command from there. The worktree was only ever needed to read `.gitlab/build_agent.yaml` from the right commit, since every other step (listing tags, validating `--ref`, creating and pushing the tag) keys off ref/object names that any clone resolves the same way. Read the YAML via `git show <ref>:.gitlab/build_agent.yaml` and pass an explicit `ref` to `git tag` (`origin/<target>` by default, the resolved commit when `--ref` is supplied). The user's local checkout and branches are never touched. Side effects: - Drops `WORKTREE_BASE`, `_create_worktree`, `_remove_worktree`, `_prepare_working_dir`, and the worktree `try/finally`. - Closes a silent-data-loss bug: `git worktree add -B <branch>` force-resets a pre-existing local `<branch>` to the remote tip, orphaning any local-only commits on it. - Reads the YAML at the actual commit being tagged when `--ref` is supplied, rather than at the branch tip. - Removes the implicit `git pull origin <branch>` that the no-worktree path used to do — tagging no longer mutates local branch state under any flag combination. * Apply round 4 review feedback - Move the `< 1` guard into `_parse_rc_value` so `--rc 0` is rejected via `click.UsageError` (exit code 2) like every other `--rc` parse failure, instead of via `app.abort` (exit code 1) after the prompt branch. The interactive-prompt branch still aborts on `< 1`, which is now the only path that reaches that check. - Add `git` as an explicit parameter to `_ensure_branch_on_origin` to match the other git-using helpers. - Tighten the worktree-regression guard in tests: filter both `run` and `capture` calls, since `git worktree` operations can go through either entry point. - `_make_ref_dispatcher` now delegates to `_capture_dispatch` for subcommands it doesn't explicitly handle, removing the duplicated `ls-remote` literal. --------- Co-authored-by: Alexey Pilyugin <alexey.pilyugin@datadoghq.com>
* Add ddev release test-agent command
Dispatch both .github/workflows/test-agent.yml and test-agent-windows.yml
against a release branch or tag, with Agent image resolution and validation
against registry.datadoghq.com. The command resolves the latest published
*-rc.N tag for a branch input, validates Linux and Windows (servercore)
manifests, shows a confirmation panel, then fires both workflow_dispatch
calls in parallel via the async GitHub client.
Extends AsyncGitHubClient.create_workflow_dispatch with a typed
return_run_details kwarg (overloads) so the new 200 response shape
(workflow_run_id, run_url, html_url) is parsed into a WorkflowDispatchResult
when requested, and the result panel links directly to each run.
* Add changelog entry
* Apply review feedback: tighten typing, broaden registry handling, expand tests
- Rename _MANIFEST_ACCEPT to MANIFEST_ACCEPT per AGENTS.md (no underscore prefix on module constants).
- Move asyncio import to module level; drop duplicate import.
- Narrow _extract_run_urls signature to Sequence[GitHubResponse[WorkflowDispatchResult] | BaseException]; remove three type:ignore comments and the unused owner/repo/ref params.
- Surface the originating exception (__cause__) in the abort message after a dispatch failure.
- Combine messages when both Linux and Windows dispatches fail.
- tag.lstrip('v') -> tag.removeprefix('v') for accurate intent.
- Document REPO_OWNER design choice with a short comment.
- Add one-line docstrings to manifest_url and tags_list_url.
- Request a large page (n=10000) when listing registry tags; the Agent registry has many years of tags and the default page may not include the current release cycle.
- Type-annotate test fixtures and test functions.
- Parametrize test_branch_resolves_latest_rc over workflow_id; add a mirror test for the Linux-fails partial-dispatch case; add a both-fail case; cover 401/403/503 in the manifest error test; cover null and missing 'tags' key in the tags-list parser.
* Apply round-2 review feedback + ruff 0.11.10 format
Review feedback:
- Pass inputs dict through to _print_plan so the plan display is derived
from the same source the dispatch sees (no more hardcoded 'true'/'false'
drifting from the inputs values).
- Use string values ('true', 'false') for type:boolean workflow inputs to
match what the GitHub workflow_dispatch API documents.
- Replace assert-based type narrowing in _extract_run_urls with nested
isinstance checks so the flow stays sound under python -O.
- Rename surviving_label -> failing_label in the parametrized partial-dispatch
test (the assertion targets the failing side's message, not the surviving).
CI fix:
- Reformat with ruff 0.11.10 (the version pinned by the ddev CI workflow);
my local hatch env shipped 0.15.11 which produced minor multi-line layout
differences. Affects test-agent.yml lint for both Linux and Windows
matrices.
* Harden ddev release test-agent error handling
- Abort early when github.token is empty instead of leaking the
AsyncGitHubClient ValueError out of asyncio.run.
- Abort with a friendly message when the public Agent registry returns
a non-404 HTTP error from manifest_exists or list_agent_rc_tags,
rather than surfacing the raw httpx traceback.
- Narrow the inputs dict to dict[str, str] all the way through
_dispatch_both / _dispatch_both_async; the workflow_dispatch API
rejects non-string values, so an accidental non-string value now
becomes a type error at the closest boundary to the API call.
- Drop the cause-formatting suffix on the dispatch-failure abort; the
RuntimeError messages already embed the underlying error so the
cause would render twice.
- Drop the unused ref parameter from _print_result.
- Add tests covering timeout and connection-error propagation from
the registry helpers.
* Hardcode dispatch target to DataDog/integrations-core
- Introduce REPO_NAME='integrations-core' constant alongside REPO_OWNER
and use it in the workflow_dispatch call, so a user with ddev pointed
at integrations-extras/marketplace/a fork doesn't silently dispatch
to DataDog/<wrong-repo>. Both test-agent.yml workflows only exist on
integrations-core, matching the existing owner hardcoding rationale.
- Lift the duplicate inline 'import httpx' to a top-level import so
the module's external dependencies are visible at a glance.
- Add tests for the empty-token guard and for the two registry HTTP
error paths that translate to friendly app.abort messages.
* Extract docker_registry utility and tighten test-agent workflow checks
- Move generic Docker Registry v2 helpers (manifest probe, tag listing with
Link: rel=next pagination) into ddev.utils.docker_registry so they can be
reused by other release tooling. The agent-specific RC filter stays in
cli.release.test_agent.registry as a thin wrapper.
- Read workflow files from origin/<branch> so a branch the user has not yet
fetched no longer reads as a missing workflow file. Distinguish "file not
in tree" from "ref not in local clone" from other git failures so the
abort message points at the real problem.
- Move httpx and asyncio imports back inside the functions that use them;
the registry module is lazy-imported, so the top-level imports were paid
on every ddev invocation (including ddev --help).
- Use add_note to keep the Windows traceback attached when both dispatches
fail. Wrap the result print in try/except/else so the success-only call
site is obvious.
- Take versions (not full image refs) into _validate_images_exist; drop the
rsplit round-trip.
- Note in the inputs dict that test-py2='false' on Windows is intentional.
* Lift asyncio import to module top
* Surface both errors when test-agent dispatches both fail
- Fold the Linux and Windows error reprs into the RuntimeError message so
app.abort(str(e)) renders both. The previous add_note(...) approach
stored the Windows error in __notes__, which str(exc) does not include,
so the Windows side was silently dropped from the abort output.
- Re-raise CancelledError and other non-Exception BaseException subclasses
from _extract_run_urls before treating results as dispatch failures.
asyncio.gather(return_exceptions=True) captures cancellation into the
result list; wrapping it in RuntimeError would hide flow-control intent.
- Pass the github token directly into _dispatch_both instead of threading
the whole Application object through. Decouples the helper.
- Centralize the httpx.HTTPError -> app.abort translation in a
_registry_errors context manager; removes the duplicated try/except in
_resolve_version and _validate_images_exist and keeps the lazy httpx
import in one place.
- Render the dispatch plan via display_info so it lands on stderr
alongside the surrounding progress lines; piping the command no longer
splits the pre-dispatch narrative across stdout and stderr.
- Replace the hand-rolled Link-header parser in docker_registry.list_tags
with httpx.Response.links, which handles RFC 5988 quoting and
multi-link rels correctly.
- Strengthen test_both_dispatches_fail_combine_messages to assert both
Windows: and a count of 2 of the shared error repr so the regression
cannot recur.
* Split test-agent helpers into validation/images/dispatch modules
Move the supporting logic for `ddev release test-agent` into sibling modules
so the command file reads as the orchestration story it tells:
- validation.py — input regex checks, git ref existence on origin, and
workflow-file presence on the resolved ref (including the file-missing
vs ref-not-fetched vs unknown-git-failure dispatch in the error path).
- images.py — RC version resolution, image ref construction, manifest
existence checks, and the registry_errors context manager that
translates httpx errors into clean abort messages.
- dispatch.py — the parallel workflow_dispatch orchestration. The async
coroutine is nested inside dispatch_both so the reader sees the full
flow in one function rather than bouncing between two near-empty
stack frames. extract_run_urls keeps the partial/total-failure surface
next to the dispatch.
`__init__.py` now contains only the Click command plus the small
`_print_plan`/`_print_result` display helpers. Every sibling module is
imported lazily inside the command body so `ddev --help` only pays for
`click` from this package.
Also narrow `AsyncGitHubClient.create_workflow_dispatch`'s `inputs`
parameter from `dict[str, Any] | None` to `dict[str, str] | None`
across both `@overload`s and the implementation. The workflow_dispatch
API contract is string-to-string (booleans are matched against the
lowercase string form), every in-tree caller already passes a
`dict[str, str]`, and the wider type silently accepted values that
would surface as runtime 422s from GitHub. The fake test client mirror
is updated to match.
* Auto-fetch the target ref and model branch/tag as a sum type
Make the user's `--branch` or `--tag` choice a typed `Branch | Tag` produced by
`validate_input`, and have every downstream helper take that `ReleaseTarget`
instead of `(branch: str | None, tag: str | None)`. This puts the "exactly one
is set" invariant in the type system and removes the type-narrowing `assert`s
that would otherwise turn into an `AssertionError` with no context if anyone
broke the invariant.
While at it, drop the `git ls-remote` probe + "please run `git fetch` and try
again" hint and fetch the ref ourselves. The new `fetch_target` runs
`git fetch --quiet --depth=1 origin refs/heads/<branch>:refs/remotes/origin/<branch>`
(or the equivalent `refs/tags/...:refs/tags/...` for `--tag`), which both confirms
the ref exists on origin and populates the local refs we need to read the
workflow files. If `git fetch` reports `couldn't find remote ref`, the abort
message stays the same as before (`Branch X not found on origin`); other git
errors surface verbatim through `Failed to fetch ... from origin: ...`.
Tests now mock `GitRepository.run` (the fetch) instead of `GitRepository.capture`
(the ls-remote). Two new tests pin the exact refspec the command must send so a
future refactor that breaks the fetch shape can't slip through. The
"please-fetch-first" test goes away; that branch is unreachable now.
* Define workflow names in validation; symmetric error shape; cover CancelledError
- Move WORKFLOW_LINUX/WORKFLOW_WINDOWS from dispatch.py to validation.py and
have dispatch.py import them from validation. Inverts the previous arrow so
the layer that runs first owns the constants; validation no longer pulls in
dispatch's async/HTTP modules at import time.
- Make fetch_target's OSError handler use `if/else` for symmetry with
verify_workflows_present_on_ref. Behavior unchanged; the two helpers now
read identically instead of relying on `app.abort`'s `NoReturn` to keep the
trailing abort unreachable.
- Add direct unit tests for extract_run_urls. The existing test_command tests
only feed httpx.HTTPStatusError (an Exception), so the
BaseException-but-not-Exception re-raise that lets CancelledError /
KeyboardInterrupt propagate was untested in CI. New tests pin both the
flow-control propagation contract and the both-failure message shape.
* Render dispatch result as a panel and space out the command's output blocks
- Add blank-line separators between each phase of the command (fetch, version
resolution, image validation, dispatch plan, final result) so the output
reads as distinct sections rather than one continuous stream.
- Replace the trailing `display_success` + two `display_pair` calls with a
rich Panel matching the look of `ddev release port-commit`'s completion
summary. The two run URLs sit inside a cyan-bordered "Workflows dispatched"
panel with bold-aligned Linux/Windows labels.
* Allow forced test-agent branch fetch
* Add test-agent workflow monitoring
* Fix mypy errors in test-agent module
- dispatch.py: declare DispatchOutcome as a PEP 695 type alias so mypy
recognises it as a type (the previous TYPE_CHECKING-guarded assignment
read as a variable on mypy 2.1).
- validation.py: validate both branch/tag invariants up front and assert
the remaining one is set, removing the trailing app.abort that mypy
refused to credit as a function terminator.
* Match all patch RCs when resolving --branch in test-agent
* Tighten test-agent types and harden error paths
- Move REPO_OWNER/REPO_NAME from dispatch.py to validation.py so monitoring
no longer pulls dispatch's async/HTTP module just for two strings.
- Narrow monitor_workflows / monitor_dispatched_workflows first parameter
from Application to Terminal — matches what the body actually uses and
what the tests already pass.
- Tighten extract_dispatched_workflows input to tuple[DispatchOutcome,
DispatchOutcome] so the 2-result contract is explicit at the type level.
- Widen the monitor_dispatched_workflows guard from RuntimeError to
Exception so httpx network failures abort cleanly with the standard
"Failed to monitor workflows" message.
- Guard list_tags against non-JSON 2xx responses so registry_errors
translates them into a clean abort instead of a raw ValueError.
* Make test-agent monitor resilient and quieter
- Tolerate transient httpx errors during polling: keep the prior monitor
state instead of aborting the entire monitor on one bad request.
- Emit a single final panel in both interactive and non-interactive paths
so CI logs no longer get flooded with per-poll panels.
- Move DispatchedWorkflow under TYPE_CHECKING in monitoring.py so importing
monitoring does not eagerly load dispatch and its async machinery.
- Surface the dispatched-run html_urls in the monitor-failed abort message
so the user can resume monitoring manually.
- Tighten test_dispatch fixtures from list[...] to tuple[...] to match the
production signature.
- Annotate the FakeAsyncGitHubClient.list_workflow_run_jobs stub with
AsyncIterator[GitHubResponse[Any]] for consistency.
* Format test_github_async.py with ruff
---------
Co-authored-by: Alexey Pilyugin <alexey.pilyugin@datadoghq.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )